home *** CD-ROM | disk | FTP | other *** search
- ; $Id: tetris.pro,v 1.2 1996/12/17 23:42:52 ali Exp $
-
- ;======================================================================
- ; IDL Tetris,
- ; Ray Sterner, 23 and 25 June, 1991
- ;
- ; IDL version of Tetris.
- ; This program is composed of the following routines:
- ;
- ; t_init = initializes the screen and internal arrays.
- ; Sets up colors and shape tables.
- ; t_next = selects next piece to play.
- ; t_drop = Drops the piece down one position.
- ; t_left = Moves piece one position left.
- ; t_right = Moves piece one position right.
- ; t_rot = Rotates piece by 90 CCW.
- ; t_plot = Plots or erases piece.
- ; t_score = Handles a score, lights up line
- ; and squeezes it out.
- ; tetris = Main control program.
- ;
- ;======================================================================
- ;----- t_init.pro = tetris init ----------
- ; R. Sterner, 23 Jun, 1991
-
- pro t_init, wt, lev, bell=bell
-
- common t_com, t_nx, t_ny, t_brd, t_p, t_seed, t_r, t_x, t_y, $
- t_pxa, t_pya, t_px, t_py, t_ca, t_c, $
- t_bell, t_wait, t_pflst, t_pfxa, t_pfya, t_pfx, t_pfy, $
- t_pc, t_hpc, t_ln, t_hln, t_sc, t_hsc
- ;-------- Common variables -------------
- ; t_nx, t_ny = X and Y size of playing board.
- ; t_brd = playing board.
- ; t_p = current playing piece (used only in t_next?).
- ; t_seed = random seed used in t_next to get next piece.
- ; t_r = current rotation (0-3).
- ; t_x, t_y = current reference point. This is what drops each
- ; cycle, and can be moved left and right.
- ; t_pxa, t_pya = X and Y offset for all pieces.
- ; t_px, t_py = X and Y offsets for current piece.
- ; t_ca = colors for all pieces.
- ; t_c = current piece color.
- ; t_bell = Ring bell for each line scored?
- ; t_wait = drop cycle delay time.
- ; t_pflst = array of last element numbers for piece outlines.
- ; t_pfxa, t_pfya = table of all piece outlines, all rotations.
- ; t_pfx, t_pfy = current piece outline.
- ; t_pc, t_hpc = # pieces played in game and IDL session.
- ; t_ln, t_hln = # lines scored in game and IDL session.
- ; t_sc, t_hsc = score for game and IDL session.
- ;-------------------------------------------------
-
- ;-------- init board --------
- t_bell = 0
- if keyword_set(bell) then t_bell = 1 ; Ring bell when line complete?
- if n_elements(wt) eq 0 then wt = -1. ; Time delay.
- if wt eq -1. then wt = 0.05 ; Default time delay.
- t_wait = wt ; Wait in sec between drops.
- if n_elements(t_hln) eq 0 then t_hln = 0 ; High scores.
- if n_elements(t_hpc) eq 0 then t_hpc = 0
- if n_elements(t_hsc) eq 0 then t_hsc = 0
- t_nx = 11 ; Size in X. (+1)
- t_ny = 21 ; Size in Y. (+1)
- t_brd = bytarr(t_nx-1, t_ny) ; Board.
-
- ;----- Set up random starting pieces -----
- ;----- If level < 0 then plot these pieces in gray (8) ----
- if abs(lev) gt 0 then begin
- lset = (byte(randomu(i,t_nx-1,abs(lev))*8)<7B)* $
- byte(randomu(i,t_nx-1,abs(lev)) gt .5)
- if lev lt 0 then lset = 8*(lset ne 0)
- t_brd[0,0] = lset
- endif
-
-
- ;-------- Set up piece color array -------
- t_ca = [1,2,3,4,5,6,7,8]
-
- ;-------- Set up pieces ------
- ;-------- As offsets: ----------
- ;--- Set up X offsets for 7 4 part pieces, each with 4 rotations --
- t_pxa = intarr(4,4,7)
- t_pxa[0,0,0] = [[0,1,0,1], $ ; Piece # 0: X X
- [0,1,0,1], $ ; X X
- [0,1,0,1], $
- [0,1,0,1]]
-
- t_pxa[0,0,1] = [[-2,-1,0,1], $ ; Piece # 1: X X X X
- [0,0,0,0], $
- [-2,-1,0,1],$
- [0,0,0,0]]
-
- t_pxa[0,0,2] = [[-1,0,1,0], $ ; Piece # 2: X X X
- [0,0,0,1], $ ; X
- [-1,0,1,0], $
- [0,0,0,-1]]
-
- t_pxa[0,0,3] = [[-1,0,0,1], $ ; Piece # 3: X X
- [0,0,-1,-1], $ ; X X
- [0,-1,-1,-2], $
- [-1,-1,0,0]]
-
- t_pxa[0,0,4] = [[-1,0,0,1], $ ; Piece # 4: X X
- [-1,-1,0,0], $ ; X X
- [0,-1,-1,-2], $
- [0,0,-1,-1]]
-
- t_pxa[0,0,5] = [[-1,0,1,1],$ ; Piece # 5: X X X
- [0,0,0,1], $ ; X
- [1,0,-1,-1], $
- [0,0,0,-1]]
-
- t_pxa[0,0,6] = [[1,0,-1,-1],$ ; Piece # 6: X X X
- [0,0,0,1],$ ; X
- [-1,0,1,1],$
- [0,0,0,-1]]
-
- ;--- Set up Y offsets for 7 4 part pieces, each with 4 rotations --
- t_pya = intarr(4,4,7)
-
- t_pya[0,0,0] = [[0,0,1,1],[0,0,1,1],[0,0,1,1],[0,0,1,1]]
- t_pya[0,0,1] = [[0,0,0,0],[-2,-1,0,1],[0,0,0,0],[-2,-1,1,0]]
- t_pya[0,0,2] = [[0,0,0,-1],[-1,0,1,0],[0,0,0,1],[1,0,-1,0]]
- t_pya[0,0,3] = [[0,0,-1,-1],[0,-1,-1,-2],[-1,-1,0,0],[-1,0,0,1]]
- t_pya[0,0,4] = [[-1,-1,0,0],[0,-1,-1,-2],[0,0,-1,-1],[-1,0,0,1]]
- t_pya[0,0,5] = [[0,0,0,-1],[-1,0,1,1],[0,0,0,1],[1,0,-1,-1]]
- t_pya[0,0,6] = [[0,0,0,-1],[1,0,-1,-1],[0,0,0,1],[-1,0,1,1]]
-
- ;------ Setup pieces as outlines ---------
- t_pflst = [3,3,7,7,7,5,5] ; Last outline point #.
- t_pfxa = intarr(8,4,7)
- t_pfxa[0,0,0] = [[0,2,2,0,0,0,0,0],$
- [0,2,2,0,0,0,0,0],$
- [0,2,2,0,0,0,0,0],$
- [0,2,2,0,0,0,0,0]]
- t_pfxa[0,0,1] = [[-2,2,2,-2,0,0,0,0],$
- [0,1,1,0,0,0,0,0],$
- [-2,2,2,-2,0,0,0,0],$
- [0,1,1,0,0,0,0,0]]
- t_pfxa[0,0,2] = [[-1,0,0,1,1,2,2,-1],$
- [0,1,1,2,2,1,1,0],$
- [-1,2,2,1,1,0,0,-1],$
- [-1,0,0,1,1,0,0,-1]]
- t_pfxa[0,0,3] = [[-1,0,0,2,2,1,1,-1],$
- [-1,0,0,1,1,0,0,-1],$
- [-2,-1,-1,1,1,0,0,-2],$
- [-1,0,0,1,1,0,0,-1]]
- t_pfxa[0,0,4] = [[-1,1,1,2,2,0,0,-1],$
- [0,1,1,0,0,-1,-1,0],$
- [-2,0,0,1,1,-1,-1,-2],$
- [0,1,1,0,0,-1,-1,0]]
- t_pfxa[0,0,5] = [[-1,1,1,2,2,-1,0,0],$
- [0,1,1,2,2,0,0,0],$
- [-1,2,2,0,0,-1,0,0],$
- [-1,1,1,0,0,-1,0,0]]
- t_pfxa[0,0,6] = [[-1,0,0,2,2,-1,0,0],$
- [0,2,2,1,1,0,0,0],$
- [-1,2,2,1,1,-1,0,0],$
- [0,1,1,-1,-1,0,0,0]]
- t_pfya = intarr(8,4,7)
- t_pfya[0,0,0] = [[0,0,2,2,0,0,0,0],$
- [0,0,2,2,0,0,0,0],$
- [0,0,2,2,0,0,0,0],$
- [0,0,2,2,0,0,0,0]]
- t_pfya[0,0,1] = [[0,0,1,1,0,0,0,0],$
- [-2,-2,2,2,0,0,0,0],$
- [0,0,1,1,0,0,0,0],$
- [-2,-2,2,2,0,0,0,0]]
- t_pfya[0,0,2] = [[0,0,-1,-1,0,0,1,1],$
- [-1,-1,0,0,1,1,2,2],$
- [0,0,1,1,2,2,1,1],$
- [0,0,-1,-1,2,2,1,1]]
- t_pfya[0,0,3] = [[0,0,-1,-1,0,0,1,1],$
- [-2,-2,-1,-1,1,1,0,0],$
- [0,0,-1,-1,0,0,1,1],$
- [-1,-1,0,0,2,2,1,1]]
- t_pfya[0,0,4] = [[-1,-1,0,0,1,1,0,0],$
- [-2,-2,0,0,1,1,-1,-1],$
- [-1,-1,0,0,1,1,0,0],$
- [-1,-1,1,1,2,2,0,0]]
- t_pfya[0,0,5] = [[0,0,-1,-1,1,1,0,0],$
- [-1,-1,1,1,2,2,0,0],$
- [0,0,1,1,2,2,0,0],$
- [-1,-1,2,2,0,0,0,0]]
- t_pfya[0,0,6] = [[-1,-1,0,0,1,1,0,0],$
- [-1,-1,0,0,2,2,0,0],$
- [0,0,2,2,1,1,0,0],$
- [-1,-1,2,2,1,1,0,0]]
-
- ;------- Scale board to screen --------
- plot,[0,t_nx-1],[0,t_ny-1],position=[.1,.1,.4,.9],/xsty,/ysty,/nodata
- ;------- Outline board -----------------
- erase
- polyfill, [-1,t_nx, t_nx, -1], [-1, -1, t_ny, t_ny], $
- color=10
- polyfill, [-1,t_nx, t_nx, -1], [-1, -1, t_ny, t_ny], $
- color=9, spacing=.15, orient=0
- polyfill, [-1,t_nx, t_nx, -1], [-1, -1, t_ny, t_ny], $
- color=9, spacing=.15, orient=90
- polyfill,[-.2,t_nx-.8,t_nx-.8,-.2],$
- [-.2,-.2,t_ny-.8,t_ny-.8]
- polyfill,[0,1,1,0]*(t_nx-1),[0,0,1,1]*(t_ny-1), color=0
- plots,[-1,t_nx,t_nx,-1,-1],[-1,-1,t_ny,t_ny,-1],thick=3
-
- ;------ Show starting board --------
- if abs(lev) gt 0 then begin
- for iy = 0, abs(lev) do begin
- for ix = 0, t_nx-2 do begin
- c = t_brd[ix,iy]
- polyfill, [0,1,1,0]+ix, [0,0,1,1]+iy, color=c
- endfor
- endfor
- endif
-
- ;------ Menu -----
- xyouts, 350-25, 280+30, /dev, size=1.2, '!3J = Move left'
- xyouts, 475, 280+30, /dev, size=1.2, 'L = Move right'
- xyouts, 350-25, 260+30, /dev, size=1.2, 'SPACE = Rotate'
- xyouts, 475, 260+30, /dev, size=1.2, 'H = Help'
- xyouts, 475, 240+30, /dev, size=1.2, 'Q = Quit'
- xyouts, 350-25, 240+30, /dev, size=1.2, 'S = Start'
- xyouts, 350-25, 220+30, /dev, size=1.2, 'P = Pause/unpause'
-
-
- xyouts, 420, 190, 'Game', size=1.8, /dev
- xyouts, 520, 190, 'Session', size=1.8, /dev
- xyouts, 320, 160, 'Pieces:',size=1.8, /dev
- xyouts, 320, 130, 'Lines:',size=1.8, /dev
- xyouts, 320, 100, 'Score:',size=1.8, /dev
-
- t_pc = 0 ; Current score.
- t_ln = 0
- t_sc = 0
- xyouts, /dev, 420, 160, size=1.8, strtrim(t_pc,2)
- xyouts, /dev, 520, 160, size=1.8, strtrim(t_hpc,2)
- xyouts, /dev, 420, 130, size=1.8, strtrim(t_ln, 2)
- xyouts, /dev, 520, 130, size=1.8, strtrim(t_hln, 2)
- xyouts, /dev, 420, 100, size=1.8, strtrim(t_sc, 2)
- xyouts, /dev, 520, 100, size=1.8, strtrim(t_hsc, 2)
-
-
- ;------- Load color table --------
- tvlct, $
- [0,255,255,127,255,127,255,127,128,255, 0, 0,255,255,255,255],$
- [0,127,127,255,255,127,189,255,128,255, 0,255, 0,255,255,255],$
- [0,127,255,255,127,255,127,127,128,255,255,233, 0, 0, 0,255]
-
- ;--------- Make title --------
- xyouts, 25+300, 400+15, /dev, size=3, '!17IDL Tetris', color=10
- xyouts, 25+301, 401+15, /dev, size=3, '!17IDL Tetris', color=10
- xyouts, 25+302, 402+15, /dev, size=3, '!17IDL Tetris', color=11
- xyouts, 25+303, 403+15, /dev, size=3, '!17IDL Tetris', color=11
- xyouts, 25+304, 404+15, /dev, size=3, '!17IDL Tetris', color=12
- xyouts, 25+305, 405+15, /dev, size=3, '!17IDL Tetris', color=12
- xyouts, 25+306, 406+15, /dev, size=3, '!17IDL Tetris', color=13
- xyouts, 25+307, 407+15, /dev, size=3, '!17IDL Tetris', color=13
-
- xyouts, /dev, size=2, 23+392, 370+13, '!13by', color=12
- xyouts, /dev, size=2, 23+342, 336+13, '!13Ray Sterner!3', color=12
- xyouts, /dev, size=2, 24+392, 370+14, '!13by', color=12
- xyouts, /dev, size=2, 24+342, 336+14, '!13Ray Sterner!3', color=12
- xyouts, /dev, size=2, 25+392, 370+15, '!13by', color=6
- xyouts, /dev, size=2, 25+342, 336+15, '!13Ray Sterner!3', color=6
-
-
- return
- end
-
- ;======================================================================
- ;-------- t_next = get next piece ready ------
- ; R. Sterner, 23 Jun, 1991
-
- pro t_next, pn
-
- common t_com, t_nx, t_ny, t_brd, t_p, t_seed, t_r, t_x, t_y, $
- t_pxa, t_pya, t_px, t_py, t_ca, t_c, $
- t_bell, t_wait, t_pflst, t_pfxa, t_pfya, t_pfx, t_pfy, $
- t_pc, t_hpc, t_ln, t_hln, t_sc, t_hsc
-
- if n_elements(pn) eq 0 then begin
- t_p = byte(randomu(t_seed)*7) ; Pick a random piece #.
- endif else t_p = pn ; Use selected piece number.
- t_r = 0 ; Start in standard position.
- t_c = t_ca[t_p] ; Look up piece color.
- t_px = t_pxa[*, t_r, t_p] ; Pull out correct offsets.
- t_py = t_pya[*, t_r, t_p]
- t_pfx = t_pfxa[0:t_pflst[t_p],t_r,t_p] ; Extract outline.
- t_pfy = t_pfya[0:t_pflst[t_p],t_r,t_p]
- t_x = t_nx/2 ; Starting position.
- t_y = t_ny
-
- return
- end
-
- ;======================================================================
- ;------- t_drop = drop a piece one position ------
- ; R. Sterner, 23 Jun, 1991
-
- pro t_drop, done=done, range=range
-
- common t_com, t_nx, t_ny, t_brd, t_p, t_seed, t_r, t_x, t_y, $
- t_pxa, t_pya, t_px, t_py, t_ca, t_c, $
- t_bell, t_wait, t_pflst, t_pfxa, t_pfya, t_pfx, t_pfy, $
- t_pc, t_hpc, t_ln, t_hln, t_sc, t_hsc
-
- t_plot, 0 ; Erase current position.
- t_y = t_y - 1 ; Drop one position.
-
- flag = 0 ; Undo flag.
- if min(t_y + t_py) lt 0 then flag = 1 ; Hit bottom.
- if max(t_brd[t_x+t_px, t_y+t_py]) gt 0 then flag = 1 ; Collision.
-
- done = 0 ; Assume not done yet.
- if flag eq 1 then begin ; Done.
- t_y = t_y + 1 ; Can't move down.
- t_brd[t_x+t_px, t_y+t_py] = t_c ; Update board with color.
- done = 1 ; Set done flag.
- range = [min(t_y+t_py), max(t_y+t_py)] ; Range to check.
- endif
-
- t_plot, 1 ; Plot new position.
- wait, t_wait
-
- return
- end
-
- ;======================================================================
- ;------- t_left = move piece one position left ------
- ; R. Sterner, 23 Jun, 1991
-
- pro t_left
-
- common t_com, t_nx, t_ny, t_brd, t_p, t_seed, t_r, t_x, t_y, $
- t_pxa, t_pya, t_px, t_py, t_ca, t_c, $
- t_bell, t_wait, t_pflst, t_pfxa, t_pfya, t_pfx, t_pfy, $
- t_pc, t_hpc, t_ln, t_hln, t_sc, t_hsc
-
- t_plot, 0 ; Erase current position.
-
- t_x = t_x - 1 ; Shift left 1.
-
- flag = 0 ; Undo flag.
- if min(t_x + t_px) lt 0 then flag = 1 ; Out of bounds.
- if max(t_brd[t_x+t_px, t_y+t_py]) gt 0 then flag = 1 ; Collision.
-
- if flag eq 1 then t_x = t_x + 1 ; Undo.
-
- t_plot, 1 ; Plot new position.
-
- return
- end
-
-
- ;======================================================================
- ;------- t_right = move piece one position right ------
- ; R. Sterner, 23 Jun, 1991
-
- pro t_right
-
- common t_com, t_nx, t_ny, t_brd, t_p, t_seed, t_r, t_x, t_y, $
- t_pxa, t_pya, t_px, t_py, t_ca, t_c, $
- t_bell, t_wait, t_pflst, t_pfxa, t_pfya, t_pfx, t_pfy, $
- t_pc, t_hpc, t_ln, t_hln, t_sc, t_hsc
-
- t_plot, 0 ; Erase current position.
-
- t_x = t_x + 1 ; Shift right 1.
-
- flag = 0 ; Undo flag.
- if max(t_x + t_px) gt (t_nx-2) then flag = 1 ; Out of bounds.
- if max(t_brd[t_x+t_px, t_y+t_py]) gt 0 then flag = 1 ; Collision.
-
- if flag eq 1 then t_x = t_x - 1 ; Undo.
-
- t_plot, 1 ; Plot new position.
-
- return
- end
-
- ;======================================================================
- ;------- t_rot = rotate a piece one position ------
- ; R. Sterner, 23 Jun, 1991
-
- pro t_rot
-
- common t_com, t_nx, t_ny, t_brd, t_p, t_seed, t_r, t_x, t_y, $
- t_pxa, t_pya, t_px, t_py, t_ca, t_c, $
- t_bell, t_wait, t_pflst, t_pfxa, t_pfya, t_pfx, t_pfy, $
- t_pc, t_hpc, t_ln, t_hln, t_sc, t_hsc
-
- t_plot, 0 ; Erase current position.
-
- t_r = (t_r + 1) mod 4 ; Rotate.
- t_px = t_pxa[*,t_r,t_p] ; Extract new offsets.
- t_py = t_pya[*,t_r,t_p]
- t_pfx = t_pfxa[0:t_pflst[t_p],t_r,t_p] ; Extract outline.
- t_pfy = t_pfya[0:t_pflst[t_p],t_r,t_p]
-
- ;---- Check for out of bounds or collision. -----
- flag = 0 ; Undo flag.
- ;------ Don't rotate out the sides ---------
- if (min(t_x+t_px) lt 0) or (max(t_x+t_px) gt (t_nx-2)) then flag = 1
- ;------ Don't rotate out the bottom -----
- if (min(t_y+t_py) lt 0) then flag = 1
- ;------ Check collision with another piece ------
- if max(t_brd[t_x+t_px, t_y+t_py]) gt 0 then flag = 1 ; Collision.
- if flag eq 1 then begin ; Undo.
- t_r = (t_r + 3) mod 4 ; Rotate 270 = -90.
- t_px = t_pxa[*,t_r,t_p] ; Extract new offsets.
- t_py = t_pya[*,t_r,t_p]
- t_pfx = t_pfxa[0:t_pflst[t_p],t_r,t_p] ; Extract outline.
- t_pfy = t_pfya[0:t_pflst[t_p],t_r,t_p]
- endif
-
- t_plot, 1 ; Plot new position.
-
- return
- end
-
- ;======================================================================
- ;------ t_plot.pro = Erase or draw current tetris piece ---------
- ; R. Sterner, 23 Jun, 1991
-
- pro t_plot, flag
-
- common t_com, t_nx, t_ny, t_brd, t_p, t_seed, t_r, t_x, t_y, $
- t_pxa, t_pya, t_px, t_py, t_ca, t_c, $
- t_bell, t_wait, t_pflst, t_pfxa, t_pfya, t_pfx, t_pfy, $
- t_pc, t_hpc, t_ln, t_hln, t_sc, t_hsc
-
- c = 0
- if flag eq 1 then c = t_c
-
- if max(t_y+t_pfy) lt t_ny then begin
- polyfill, t_x+t_pfx, t_y+t_pfy, color=c
- endif
-
- return
- end
-
- ;======================================================================
- ;------- t_score = Look for and process a score. ------
- ; R. Sterner, 23 Jun, 1991
-
- pro t_score, r
-
- common t_com, t_nx, t_ny, t_brd, t_p, t_seed, t_r, t_x, t_y, $
- t_pxa, t_pya, t_px, t_py, t_ca, t_c, $
- t_bell, t_wait, t_pflst, t_pfxa, t_pfya, t_pfx, t_pfy, $
- t_pc, t_hpc, t_ln, t_hln, t_sc, t_hsc
-
- ;--------- Add score for this piece --------
- xyouts, 420, 100, /dev, size=1.8, strtrim(t_sc,2), color=0
- t_sc = t_sc + 7 ; Each piece worth 7 pts.
- xyouts, 420, 100, /dev, size=1.8, strtrim(t_sc,2)
-
- count = 0 ; Lines scored on piece.
- rn = (r[0]+indgen(r[1]-r[0]+1))<(t_ny-1) ; Range to check.
- for i = 0, n_elements(rn)-1 do begin ; Check each line.
- if total(t_brd[*,rn[i]] eq 0) eq 0 then begin ; Score.
- ;--- light up score line ----
- xp = [0.01,.99,.99,0.01]*(t_nx-1)
- yp = [0.05,0.05,.99,.99]+rn[i]
- polyfill, xp,yp,color=0,spacing=.1,orient=0
- polyfill, xp,yp,color=0,spacing=.1,orient=90
- wait, 0
- ;--- ring bell -----
- if t_bell then print,string(7b),form='($,a1)'
- ;--- Collapse board -------
- t_brd[0,rn[i]] = t_brd[*,(rn[i]+1):*]
- ;--- Repaint screen board -----
- tmp = fltarr(t_ny)
- for j = 0, t_ny-1 do tmp[j] = total(t_brd[*,j])
- mx = 1+max(where(tmp ne 0))
- for z = 0.8, 0., -.2 do begin
- for iy = rn[i], mx do begin
- for ix = 0, t_nx-2 do begin
- c = t_brd[ix,iy]
- polyfill, [0,1,1,0]+ix, (z+[0,0,1,1]+iy)<(t_ny-1), color=c
- endfor
- endfor
- endfor ; Z
- ;--- Decrement range ------
- rn = rn - 1
- ;---- Count scored line -----
- count = count + 1
- ;--- Update score board -----
- xyouts, 420, 130, /dev, size=1.8, strtrim(t_ln,2), color=0
- t_ln = t_ln + 1
- xyouts, 420, 130, /dev, size=1.8, strtrim(t_ln,2)
- xyouts, 420, 100, /dev, size=1.8, strtrim(t_sc,2), color=0
- t_sc = t_sc + 22 ; Each line worth 22 pts.
- xyouts, 420, 100, /dev, size=1.8, strtrim(t_sc,2)
- endif
- endfor
-
- ;-------- Check for a tetris (4 lines scored on 1 piece) ----
- if count eq 4 then begin
- xyouts, 420, 100, /dev, size=1.8, strtrim(t_sc,2), color=0
- t_sc = t_sc + 48 ; 48 extra points.
- xyouts, 420, 100, /dev, size=1.8, strtrim(t_sc,2)
- endif
-
- return
- end
-
- ;======================================================================
- ;------- t_help.pro = display help text --------
- ; R. Sterner, 4 Aug, 1991
-
- pro t_help
-
- ver = WIDGET_INFO(/VERSION)
- if ver.style eq 'MS Windows' then device, set_display=2
- print,' '
- print,' Tetris has 7 different playing pieces which drop down'
- print,' from the top of the screen. Points are scored by'
- print,' fitting these pieces together to form horizontal rows'
- print,' having no gaps. Such complete rows dissolve away and add'
- print," to the player's score. Pieces may be moved left and right"
- print,' and rotated to fit together. The more rows completed the'
- print,' higher the score each newly completed row is worth.'
- print,' Extra credit is given for completing 4 rows at the same'
- print,' time. Upper or lower case key commands may be used, except'
- print,' that the Q (quit) command must be upper case.'
- print,' Both the current game scores and the highest score during'
- print,' the current session of IDL are displayed.'
- print,' '
- print,' The first version of this project was written using PC IDL'
- print,' in an afternoon as a test of the capabilities of IDL on a'
- print,' 386 class machine.'
- print,'
- txt = ''
- read,' Press RETURN to continue', txt
- if ver.style eq 'MS Windows' then device, set_display=3
- return
- end
-
- ;======================================================================
- ;;------ tetris.pro main tetris routine ------
- ; R. Sterner, 23 Jun, 1991
-
- pro tetris, wait=wt, level=lev, help=hlp, bell=bell, $
- top=top
-
- ;+
- ; NAME:
- ; TETRIS
- ;
- ; PURPOSE:
- ; IDL version of the falling blocks game Tetris.
- ;
- ; The object of this game is to build solid rows of blocks from the
- ; differently-shaped falling pieces.
- ;
- ; CATEGORY:
- ; Games.
- ;
- ; CALLING SEQUENCE:
- ; TETRIS
- ;
- ; INPUTS:
- ; No required inputs.
- ;
- ; OUTPUTS:
- ; No explicit outputs.
- ;
- ; OPTIONAL KEYWORD PARAMETERS:
- ; WAIT: The delay between moves in seconds. This parameter adjusts
- ; the playing speed. The default is 0.05, which may be too
- ; low for faster machines (or beginning players).
- ;
- ; LEVEL: Level of random starting pieces, default = 0.
- ;
- ; HELP: Set this keyword to display help text.
- ;
- ; BELL: Set this keyword to ring the bell for each line scored.
- ;
- ; COMMON BLOCKS:
- ; Some.
- ;
- ; SIDE EFFECTS:
- ; A window is created for the game.
- ; Interaction is via keyboard and display.
- ;
- ; MODIFICATION HISTORY:
- ; Written by Ray Sterner, Johns-Hopkins Applied Physics Research Lab
- ; 23 and 25 June, 1991
- ;-
-
- common t_com, t_nx, t_ny, t_brd, t_p, t_seed, t_r, t_x, t_y, $
- t_pxa, t_pya, t_px, t_py, t_ca, t_c, $
- t_bell, t_wait, t_pflst, t_pfxa, t_pfya, t_pfx, t_pfy, $
- t_pc, t_hpc, t_ln, t_hln, t_sc, t_hsc
-
- if keyword_set(hlp) then begin
- print,' Play tetris game.'
- print,' tetris'
- print,' Keywords:'
- print,' WAIT=tm Seconds between pieces (def=.05).'
- print,' tm = 0 is very fast, 0.1 is slow.'
- print,' LEVEL=L Level of random starting pieces (def=0).'
- print,' If L is negative then starting pieces are gray.'
- print," /BELL means ring bell for each line scored."
- print,' TOP=tp returns highest level for each piece played.'
- print,' Games are delimited by -1s.'
- return
- endif
-
- if n_elements(wt) eq 0 then wt = -1.
- if wt eq -1. then wt = 0.05
- if n_elements(lev) eq 0 then lev = 0
-
- top = [-1] ; Start TOP array.
-
- start: t_init, wt, lev, bell=bell
-
- ;------- Find top ----------
- tmp = fltarr(t_ny)
- for j = 0, t_ny-1 do tmp[j] = total(t_brd[*,j])
- mx = 1+max(where(tmp ne 0))
- top = [top,mx]
-
- rd: k = strupcase(get_kbrd(1))
- if (k eq 'H') then begin
- t_help
- goto, rd
- endif
- if k eq 'Q' then return
- if k ne 'S' then goto, rd
-
- loop1: t_next
-
- loop2: ku = strupcase(get_kbrd(0)) ; Get key.
- if ku eq ' ' then t_rot ; Rotate.
- if ku eq 'J' then t_left ; Move left.
- if ku eq 'L' then t_right ; Move right.
- if ku eq 'Q' then goto, over ; Game over.
- if ku eq 'P' then begin ; Pause.
- ku = get_kbrd(1)
- goto, loop2
- endif
- t_drop, done=d, range=r ; Drop piece.
-
- if d eq 1 then begin ; Piece done moving.
- ;------- Find top ----------
- tmp = fltarr(t_ny)
- for j = 0, t_ny-1 do tmp[j] = total(t_brd[*,j])
- mx = 1+max(where(tmp ne 0))
- top = [top,mx]
- if min(r) ge t_ny-1 then begin ; Game over?
- goto, over
- endif
- ;------ Erase current score. ------
- xyouts, /dev, 420, 160, size=1.8, strtrim(t_pc,2),color=0
- t_pc = t_pc + 1
- xyouts, /dev, 420, 160, size=1.8, strtrim(t_pc,2)
- t_score, r ; Update score.
- goto, loop1
- endif
-
- goto, loop2
-
- ;------ Game over -------
- over: polyfill, [0,1,1,0]*(t_nx-1), [0,0,1,1]*(t_ny-1),$
- color=0, spacing=.1, orient=0
- polyfill, [0,1,1,0]*(t_nx-1), [0,0,1,1]*(t_ny-1),$
- color=0, spacing=.1, orient=90
-
- ;-------- Wait for another start command. ------
- loopw: ku = strupcase(get_kbrd(1))
-
-
- ;--------- Update session max values. -----
- if (ku eq 'S') or (ku eq 'Q') then begin
- xyouts,/dev,size=1.8,520,160,strtrim(t_hpc,2),color=0
- t_hpc = t_hpc > t_pc
- xyouts,/dev,size=1.8,520,160,strtrim(t_hpc,2)
- xyouts,/dev,size=1.8,520,130,strtrim(t_hln,2),color=0
- t_hln = t_hln > t_ln
- xyouts,/dev,size=1.8,520,130,strtrim(t_hln,2)
- xyouts,/dev,size=1.8,520,100,strtrim(t_hsc,2),color=0
- t_hsc = t_hsc > t_sc
- xyouts,/dev,size=1.8,520,100,strtrim(t_hsc,2)
- endif
-
- ;--------- Handle S or Q ---------
- if ku eq 'S' then begin
- t_init, wt, lev, bell=bell
- top = [top,-1]
- ;------- Find top ----------
- tmp = fltarr(t_ny)
- for j = 0, t_ny-1 do tmp[j] = total(t_brd[*,j])
- mx = 1+max(where(tmp ne 0))
- top = [top,mx]
- goto, loop1
- endif
- if ku ne 'Q' then goto, loopw
-
- end
-
-
-